/***************************************************************************
 *   Copyright © 2010 by Nikolay Kornaev                                   *
 *   n.kornaev@gmail.com                                                   *
 *                                                                         *
 *                    This file is part of neuma.                          *
 *                                                                         *
 *   neuma is free software; you can redistribute it and/or modify it      *
 *   under the terms of the GNU General Public License as published by     *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   neuma is distributed in the hope that it will be useful,              *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
 ***************************************************************************/

#include <QtGui/qfontmetrics.h>
#include "BlockNeuma.h"

namespace Neuma
{
  BlockNeuma::BlockNeuma(const QString &neuma, QFontMetricsF *nFm) :
    rxMarks(QRegExp("[№4567?8*9(0=цуУнНгГщзъЪвВаАпПРлЛсСмМиИтТбБюweEyYuU\\]}dDfFgGhHcCvVbBnN<]"))
  {
//    qDebug() << __PRETTY_FUNCTION__;
    n = neuma;
    ushort ns = n.size();
    fm = nFm;
    QString part;
    bool currentPartIsMark = false;
    for (ushort i = 0; i < ns; i++)
      {
	QString ch = n.mid(i, 1);
	if ((ch.indexOf(rxMarks) == -1) && !currentPartIsMark)
	  part.append(ch);
	else if (!(ch.indexOf(rxMarks) == -1) && currentPartIsMark)
	  part.append(ch);
	else
	  {
	    if (!part.isEmpty())
	      {
		l.append(qMakePair(currentPartIsMark, part));
		part.clear();
	      }
	    part.append(ch);
	    currentPartIsMark = !currentPartIsMark;
	  }
      }
    l.append(qMakePair(currentPartIsMark, part));
/*    QString db;
    db.append("/////////////////////\nNEUMA:");
    for (ushort i = 0; i < l.size(); i++)
      {
	QString m = l.at(i).first? "MARK": "NOT mark";
	db.append(QString("\tpart %1 (%2), %3").arg(i).arg(m).arg(l.at(i).second));
      }
    qDebug() << db;
*/
  }

  ushort BlockNeuma::getPartsCount() const
  {
//    qDebug() << __PRETTY_FUNCTION__;
    return l.size();
  }

  qreal BlockNeuma::getPartWidth(const ushort partNumber) const
  {
//    qDebug() << __PRETTY_FUNCTION__;
//    qDebug() << "for part" << partNumber << "returned" << fm->width(l.at(partNumber).second);
    return fm->width(l.at(partNumber).second);
  }

  QString BlockNeuma::getPartText(const ushort partNumber) const
  {
//    qDebug() << __PRETTY_FUNCTION__;
    return l.at(partNumber).second;
  }

  bool BlockNeuma::getPartIsMark(const ushort partNumber) const
  {
//    qDebug() << __PRETTY_FUNCTION__;
    return l.at(partNumber).first;
  }

  QString BlockNeuma::getFulText() const
  {
//    qDebug() << __PRETTY_FUNCTION__;
    return n;
  }

  qreal BlockNeuma::getNW1() const
  {
//    qDebug() << __PRETTY_FUNCTION__;
//    qDebug() << "isMark?" << l.at(0).first << "text" << l.at(0).second;
    if (l.at(0).first)
      return getPartWidth(0);
    return 0;
  }

  qreal BlockNeuma::getNW2() const
  {
//    qDebug() << __PRETTY_FUNCTION__;
    ushort size = l.size(); //2
    if (!size)
      return 0;
    ushort c1 = l.at(0).first? 1: 0; //1
    ushort c2 = 1;
    if (size > 1)
      c2 = l.at(size - 1).first? size - 1 : size; //2
    qreal nW2 = 0;
    for (int i = c1; i < c2; i++)
      nW2 += getPartWidth(i);
    return nW2;
  }

  qreal BlockNeuma::getNW3() const
  {
//    qDebug() << __PRETTY_FUNCTION__;
    ushort size = l.size() - 1;
    if (!size)
      return 0;
    if (l.at(size).first)
      return getPartWidth(size);
    return 0;
  }
}
